package com.jy.datapipeline.importserver.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.jy.datapipeline.common.util.*;
import com.jy.datapipeline.common.constants.ExpConstants;
import com.jy.datapipeline.common.constants.PrefixConstants;
import com.jy.datapipeline.importserver.common.constants.KeyConstant;
import com.jy.datapipeline.importserver.common.enums.impl.DynamicTableEnum;
import com.jy.datapipeline.importserver.common.enums.impl.ReturnEnum;
import com.jy.datapipeline.common.exception.GlobalException;
import com.jy.datapipeline.common.vo.ReturnVo;
import com.jy.datapipeline.importserver.entity.ImportRule;
import com.jy.datapipeline.importserver.entity.ImportRuleTable;
import com.jy.datapipeline.importserver.entity.manager.EntityManager;
import com.jy.datapipeline.importserver.mapper.ImportRuleTableMapper;
import com.jy.datapipeline.importserver.service.ImportRuleService;
import com.jy.datapipeline.importserver.service.ImportRuleTableService;
import com.jy.datapipeline.importserver.support.ImportRuleSupport;
import com.mysql.cj.util.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @类名 ImportTableServiceImpl
 * @描述 TODO
 * @作者 白条君
 * @创建日期 2023/4/17 18:42
 * @版本 1.0
 */
@Service
public class ImportRuleTableServiceImpl implements ImportRuleTableService {

    @Resource
    private ImportRuleTableMapper importRuleTableMapper;

    @Resource
    private ImportRuleService importRuleService;

    @Override
    public ReturnVo queryByPage(Long pageNo, Long pageSize, String sourceSchema, String sourceTableName, String targetSchema, String targetTableName, String ruleId) {
        List<ImportRuleTable> importTables = importRuleTableMapper.selectTableByPage((pageNo - 1) * pageSize, pageSize, sourceSchema, sourceTableName, targetSchema, targetTableName, ruleId);
        long totalSize = importRuleTableMapper.selectTableTotalSize();
        long totalPage = PageUtil.getTotalPage(totalSize, pageSize);
        return ReturnVo.ok().put(importTables).put("totalSize", totalSize).put("totalPage", totalPage);
    }

    @Override
    public ImportRuleTable queryOneById(Long id) throws GlobalException {
        ImportRuleTable importRuleTable = importRuleTableMapper.selectByPrimaryKey(id);
        if (ObjectUtil.isNull(importRuleTable)) {
            throw new GlobalException(ExpConstants.NULL_OBJECT);
        }

        /**
         * 小写转大写
         */
        importRuleTable.setTargetSchema(importRuleTable.getTargetSchema().toUpperCase(Locale.ROOT));
        importRuleTable.setTargetTableName(importRuleTable.getTargetTableName().toUpperCase(Locale.ROOT));
        importRuleTable.setTargetColumnList(importRuleTable.getTargetColumnList().toUpperCase(Locale.ROOT));

        /**
         * 根据规则把字符串类型的字段列表为list中的字段
         */
        String targetColumnList = importRuleTable.getTargetColumnList();
        String[] columns = targetColumnList.split(",\n");

        List<ImportRuleTable.ImportColumn> importColumns = new ArrayList<>();
        for (String column : columns) {
            ImportRuleTable.ImportColumn importColumn
                    = (ImportRuleTable.ImportColumn) EntityManager.create(KeyConstant.IMPORT_RULE_TABLE_COLUMNS_KEY);
            String[] columnMetas = column.split("\\s+");
            importColumn.setColumn(columnMetas[0]);
            importColumn.setColumnType(columnMetas[1]);
            int length = columnMetas.length;
            if (length == 3) {
                String columnType = columnMetas[2];
                importColumn.setColumnFormat(columnType.substring(1, columnType.length() - 1));
            } else if (length == 4) {
                String columnType = StringUtil.concat(new StringBuffer(), columnMetas[2]," ", columnMetas[3]);
                importColumn.setColumnFormat(columnType.substring(1, columnType.length() - 1));
            }
            importColumns.add(importColumn);
        }

        importRuleTable.setImportColumns(importColumns);
        importRuleTable.setTargetColumnList(null);

        return importRuleTable;
    }

    @Override
    public List<ImportRuleTable> queryByRuleId(String ruleId) {
        return importRuleTableMapper.selectByRuleId(ruleId);
    }

    @Override
    public String queryTargetColumnListByRuleTableId(String ruleTableId) {
        return importRuleTableMapper.selectTargetColumnListByRuleTableId(ruleTableId);
    }

    @Override
    public void add(ImportRuleTable importRuleTable) {
        int res = importRuleTableMapper.insertSelective(importRuleTable);
        if (res == 0) {
            throw new GlobalException(ReturnEnum.SERVER_ERROR.getCode(), ExpConstants.ADD_FAIL);
        }
    }

    @Transactional
    @Override
    public void addRuleTable(ImportRuleTable importRuleTable) throws GlobalException {
        String isDynamicTable = importRuleTable.getIsDynamicTable();
        List<ImportRuleTable.ImportColumn> importColumns = importRuleTable.getImportColumns();

        if (StringUtils.isNullOrEmpty(importRuleTable.getSourceSchema()) || StringUtils.isNullOrEmpty(importRuleTable.getSourceTableName()) ||
        StringUtils.isNullOrEmpty(importRuleTable.getTargetSchema()) || StringUtils.isNullOrEmpty(importRuleTable.getTargetTableName()) ||
        ObjectUtil.isNull(importColumns) || StringUtils.isNullOrEmpty(isDynamicTable)) {
            throw new GlobalException(ReturnEnum.PARAM_ERROR.getCode(), ExpConstants.PARAMS_EXP);
        }

        //0代表是动态表，1代表是静态表，如果是静态表规则和规则值都为null
        if (String.valueOf(DynamicTableEnum.DYNAMIC.getCode()).equals(isDynamicTable)) {
            if (StringUtils.isNullOrEmpty(importRuleTable.getDynamicTableRule()) || importRuleTable.getDynamicTableRuleValue() == null) {
                throw new GlobalException(ReturnEnum.PARAM_ERROR.getCode(), ExpConstants.PARAMS_EXP);
            }
        } else if (String.valueOf(DynamicTableEnum.NOT_DYNAMIC.getCode()).equals(isDynamicTable)) {
            importRuleTable.setDynamicTableRule(null);
            importRuleTable.setDynamicTableRuleValue(null);
        }

        /**
         * 集合中的字段列表转为字符串
         */
        String columns = ImportRuleSupport.listConvertString(importColumns);

        importRuleTable.setTargetColumnList(columns.substring(0, columns.length() - 2));
        String ruleTableId = StringUtil.concat(new StringBuffer(), PrefixConstants.RULE_TABLE_PREFIX, "_", String.valueOf(SnowFlakeUtil.getNextId()));
        importRuleTable.setRuleTableId(ruleTableId);

        /**
         * 添加到规则记录中
         */
        int res = importRuleTableMapper.insertSelective(importRuleTable);
        if (res == 0) {
            throw new GlobalException(ReturnEnum.SERVER_ERROR.getCode(), ExpConstants.ADD_FAIL);
        }

        //修改导入表规则的更新时间
        ImportRule importRule = (ImportRule) EntityManager.create(KeyConstant.IMPORT_RULE_KEY);
        importRule.setRuleId(importRuleTable.getRuleId());
        importRule.setUpdateTime(DateTimeUtil.getNow());
        importRuleService.modifyImportRuleUpdateTime(importRule);
    }

    @Transactional
    @Override
    public void modifyRuleTable(ImportRuleTable importRuleTable) throws GlobalException {
        String isDynamicTable = importRuleTable.getIsDynamicTable();
        List<ImportRuleTable.ImportColumn> importColumns = importRuleTable.getImportColumns();
        Long id = importRuleTable.getId();

        if (StringUtils.isNullOrEmpty(importRuleTable.getSourceSchema()) || StringUtils.isNullOrEmpty(importRuleTable.getSourceTableName()) ||
                StringUtils.isNullOrEmpty(importRuleTable.getTargetSchema()) || StringUtils.isNullOrEmpty(importRuleTable.getTargetTableName()) ||
                ObjectUtil.isNull(importColumns) || StringUtils.isNullOrEmpty(isDynamicTable) || id == null) {
            throw new GlobalException(ReturnEnum.PARAM_ERROR.getCode(), ExpConstants.PARAMS_EXP);
        }

        if (isDynamicTable.equals("0") && StringUtils.isNullOrEmpty(importRuleTable.getDynamicTableRule())) {
            throw new GlobalException(ReturnEnum.PARAM_ERROR.getCode(), ExpConstants.PARAMS_EXP);
        }

        if (!StringUtils.isNullOrEmpty(importRuleTable.getDynamicTableRule()) && importRuleTable.getDynamicTableRuleValue() == null) {
            throw new GlobalException(ReturnEnum.PARAM_ERROR.getCode(), ExpConstants.PARAMS_EXP);
        }

        Date now = DateTimeUtil.getNow();
        importRuleTable.setUpdateTime(now);

        /**
         * 集合中的字段列表转为字符串
         */
        String columns = ImportRuleSupport.listConvertString(importColumns);
        importRuleTable.setTargetColumnList(columns.substring(0, columns.length() - 2));

        /**
         * 更新规则表记录
         */
        int res = importRuleTableMapper.updateByPrimaryKeySelective(importRuleTable);
        if (res == 0) {
            throw new GlobalException(ReturnEnum.SERVER_ERROR.getCode(), ExpConstants.MODIFY_FAIL);
        }

        //获取表规则关联的ruleid
        String ruleId = importRuleTableMapper.selectRuleIdById(id);

        //修改导入表规则的更新时间
        ImportRule importRule = (ImportRule) EntityManager.create(KeyConstant.IMPORT_RULE_KEY);
        importRule.setRuleId(ruleId);
        importRule.setUpdateTime(now);
        importRuleService.modifyImportRuleUpdateTime(importRule);
    }

    @Transactional
    @Override
    public void deleteRuleTable(Long id) throws GlobalException {
        Integer resource = importRuleTableMapper.selectResource(id);
        if (resource == null) {
            throw new GlobalException(ReturnEnum.SERVER_ERROR.getCode(), ExpConstants.RESOURCE_EXP);
        }

        //获取表规则关联的ruleid
        String ruleId = importRuleTableMapper.selectRuleIdById(id);

        int res = importRuleTableMapper.deleteByPrimaryKey(id);
        if (res == 0) {
            throw new GlobalException(ReturnEnum.SERVER_ERROR.getCode(), ExpConstants.DELETE_FAIL);
        }

        //修改导入表规则的更新时间
        ImportRule importRule = (ImportRule) EntityManager.create(KeyConstant.IMPORT_RULE_KEY);
        importRule.setRuleId(ruleId);
        importRule.setUpdateTime(DateTimeUtil.getNow());
        importRuleService.modifyImportRuleUpdateTime(importRule);
    }

    @Override
    public int batchAdd(List<ImportRuleTable> importRuleTableList) {
        return importRuleTableMapper.batchInsert(importRuleTableList);
    }

    @Override
    public void batchRemove(Set<String> ruleIds) {
        int size = importRuleTableMapper.batchDelete(ruleIds);
        AssertUtil.totalAffectedRows(size, ruleIds, ExpConstants.BATCH_DELETE_FAIL);
    }
}
